using Constants;
using ELF.Consul;
using ELF.Gateway.Jwt;
using ELF.Gateway.Permissions;
using ELF.Modules;
using ELF.Permissions;
using IdentityApi;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Authorization;
using Microsoft.Extensions.Http;
using Microsoft.IdentityModel.Tokens;

namespace ELF;

[DependsOn(typeof(ElfConsulModule))]
[DependsOn(typeof(ElfOcelotModule))]
public class ElfGatewayModule : IModule
{
    public async Task ConfigureServicesAsync(IHostApplicationBuilder builder)
    {
        builder.Services.AddScoped<IAuthorizationHandler, PermissionAuthorizationHandler>();
        builder.Services.AddAuthorization(options =>
        {
            options.AddPolicy(PermissionConsts.PolicyNames, policy =>
                policy.Requirements.Add(new PermissionRequirement()));
        });

        string url = builder.Configuration["OpenIddict:Issuer"] ?? throw new Exception("Identity Server address is not configured");
        //string url = await builder.GetConsulClientAsync(ServicesConsts.IdentityApi);
        builder.Services.AddAuthentication(options =>
        {
            options.DefaultScheme = "OpenIddict.Server.AspNetCore";
            options.DefaultChallengeScheme = "OpenIddict.Server.AspNetCore";
        }).AddJwtBearer("OpenIddict.Server.AspNetCore", options =>
        {
            options.Authority = url; // ��֤��������ַ
            options.RequireHttpsMetadata = false; // �������������� HTTP
            options.TokenValidationParameters = new TokenValidationParameters
            {
                ValidIssuer = url,
                ValidAudience = "api"
                //IssuerSigningKey =
                //new SymmetricSecurityKey(
                //    Convert.FromBase64String("SguGSpvaRLMwnmnxiBHRdSxRpBDSiD8+8J1qp1czuD8=")),
                //TokenDecryptionKey = new SymmetricSecurityKey(
                //    Convert.FromBase64String("na8LnVekSu5b3fgdUhyo+KuLTMVGYLtgHrTTpKCB5VY="))
            };
            // ���ӵ����¼�
            options.Events = new JwtBearerEvents
            {
                OnAuthenticationFailed = context =>
                {
                    Console.WriteLine("Auth failed: {0}", context.Exception.ToString());
                    context.Fail($"Auth failed: {context.Exception.ToString()}");
                    return Task.CompletedTask;
                },
                OnTokenValidated = JwtBearerEvent.OnTokenValidated
            };
        });

        builder.Services.AddSingleton<GatewayJwtService>();

        var identityServerAddress = builder.Configuration["OpenIddict:Issuer"];
        if (identityServerAddress == null)
            throw new Exception("Identity Server address is not configured");
        builder.Services
            .AddHttpClient<IPermissionsService, PermissionsService>(o => o.BaseAddress = new(identityServerAddress))
            .AddAuthToken();
        builder.Services.AddTransient<IPermissionsService, PermissionsService>();


        //builder.Services.AddSingleton<
        //    IAuthorizationMiddlewareResultHandler, SampleAuthorizationMiddlewareResultHandler>();

        await Task.CompletedTask;
    }

    public async Task InitializeAsync(IApplicationBuilder app)
    {
        await Task.CompletedTask;
    }
}
